import assert = require("assert");
import { DataContextFactory } from "../src/domain/fbsDataContext";
import { Guid } from "../src/common/index";
import { TableService } from './../src/service/tableService';
import { Table, Order, TableParty } from "../src/domain/model";


async function clearData() {
    let ctx = DataContextFactory.GetDataContext();
    let tables = await ctx.Table.ToList();
    for (let t of tables) {
        await ctx.Delete(t);
    }

    let tpList = await ctx.TableParty.ToList();
    for (let tp of tpList) {
        await ctx.Delete(tp);
    }
}
let tableService = new TableService();
describe("TableService Test", () => {
    let ctx = DataContextFactory.GetDataContext();
    describe("StartCleanTable", () => {
        let tablePartyIds = [];
        async function initData() {
            let store = await ctx.Store.First();
            let cIndex = store.configs.findIndex(x => x.key == "pos.table.manualCleanTable");
            store.configs[cIndex].value.enable = false;

            await ctx.Update(store);



            // 准备开始清台数据
            let tableParty = new TableParty();
            let table = new Table();

            for (let i = 1; i <= 50; i++) {
                table.id = Guid.GetGuid();
                table.name = "台桌" + i;
                table.status = "";
                await ctx.Create(table);

                tableParty.id = Guid.GetGuid();
                tableParty.tableId = table.id;
                tableParty.tableName = table.name;
                tableParty.tableGroupId = "";
                tableParty.openedTime = new Date().getTime();
                tableParty.cleaningTime = "";
                tableParty.closedTime = "";
                tableParty.status = "closed";
                await ctx.Create(tableParty);
                tablePartyIds.push(tableParty.id);
            }
        }

        describe("无台桌数据", () => {
            before(async () => {
                await clearData();
            })
            it("错误的台次编号", async () => {
                try {
                    let rst = await tableService.StartCleanTable({
                        tablePartyIds: ["dfadsdsfa"]
                    });
                } catch (e) {
                    assert.equal(e.Message, "没找到有效的台次");
                }
            });

            it("空的台次编号", async () => {
                try {
                    let rst = await tableService.StartCleanTable({
                        tablePartyIds: []
                    });
                } catch (e) {
                    assert.equal(e.Message, "没找到有效的台次");
                }
            });

            it("开始清台", async () => {
                try {
                    let rst = await tableService.StartCleanTable({
                        tablePartyIds: tablePartyIds
                    });
                } catch (e) {
                    assert.equal(e.Message, "没找到有效的台次");
                }
            });
        });


        describe("有台桌数据", () => {
            before(async () => {
                await clearData();
                await initData();
            })
            it("错误的台次编号", async () => {
                try {
                    let rst = await tableService.StartCleanTable({
                        tablePartyIds: ["dfadsdsfa"]
                    });
                } catch (e) {
                    assert.equal(e.Message, "没找到有效的台次");
                }
            });

            it("空的台次编号", async () => {
                try {
                    let rst = await tableService.StartCleanTable({
                        tablePartyIds: []
                    });
                } catch (e) {
                    assert.equal(e.Message, "没找到有效的台次");
                }
            });

            it("清台功能未开启", async () => {

                let store = await ctx.Store.First();
                let cIndex = store.configs.findIndex(x => x.key == "pos.table.manualCleanTable");
                store.configs[cIndex].value.enable = false;
                await ctx.Update(store);
                let ts = new TableService();
                let rst = await ts.StartCleanTable({
                    tablePartyIds: tablePartyIds
                })
                assert.equal(rst.length, 0, "清台功能未开始异常");
            });

            it("开始清台", async () => {
                let store = await ctx.Store.First();
                let cIndex = store.configs.findIndex(x => x.key == "pos.table.manualCleanTable");
                store.configs[cIndex].value.enable = true;
                await ctx.Update(store);
                let ts = new TableService();
                let rst = await ts.StartCleanTable({
                    tablePartyIds: tablePartyIds
                })
                assert.equal(rst.length, 50, "完成开始清台的数量不为50");
            });
        });
    })
    describe("FinishCleanTable", () => {

        let tablepartyId = Guid.GetGuid();
        let tableId = Guid.GetGuid();

        let tpId = Guid.GetGuid();
        let tId = Guid.GetGuid();

        let fTpId = Guid.GetGuid();
        let ftId = Guid.GetGuid();

        let cTpId = Guid.GetGuid();
        let ctId = Guid.GetGuid();

        let c1TpId = Guid.GetGuid();
        let c1tId = Guid.GetGuid();

        async function initData() {
            let ctx = DataContextFactory.GetDataContext();
            // 准备开始清台数据
            let tableParty = new TableParty();
            let table = new Table();
            table.id = tableId;
            table.name = "台桌1";
            table.status = "cleaning";
            await ctx.Create(table);

            tableParty.id = tablepartyId;
            tableParty.tableId = table.id;
            tableParty.tableName = table.name;
            tableParty.tableGroupId = "";
            tableParty.openedTime = new Date().getTime();
            tableParty.cleaningTime = "";
            tableParty.closedTime = "";
            tableParty.status = "cleaning";
            await ctx.Create(tableParty);

            tableParty = new TableParty();
            table = new Table();
            table.id = tId;
            table.name = "台桌2";
            table.status = "";
            await ctx.Create(table);

            tableParty.id = tpId;
            tableParty.tableId = tId;
            tableParty.tableName = table.name;
            tableParty.tableGroupId = "";
            tableParty.openedTime = new Date().getTime();
            tableParty.cleaningTime = "";
            tableParty.closedTime = "";
            tableParty.status = "closed";
            await ctx.Create(tableParty);

            tableParty = new TableParty();
            table = new Table();
            table.id = ftId;
            table.name = "台桌3";
            table.status = "cleaning";
            await ctx.Create(table);

            tableParty.id = fTpId;
            tableParty.tableId = ftId;
            tableParty.tableName = table.name;
            tableParty.tableGroupId = "";
            tableParty.openedTime = new Date().getTime();
            tableParty.cleaningTime = "";
            tableParty.closedTime = "";
            tableParty.status = "closed";
            await ctx.Create(tableParty);

            tableParty = new TableParty();
            table = new Table();
            table.id = ctId;
            table.name = "台桌4";
            table.status = "cleaning";
            await ctx.Create(table);

            tableParty.id = cTpId;
            tableParty.tableId = ctId;
            tableParty.tableName = table.name;
            tableParty.tableGroupId = "";
            tableParty.openedTime = new Date().getTime();
            tableParty.cleaningTime = "";
            tableParty.closedTime = "";
            tableParty.status = "cleaning";
            await ctx.Create(tableParty);

            tableParty = new TableParty();
            table = new Table();
            table.id = c1tId;
            table.name = "台桌4";
            table.status = "cleaning";
            await ctx.Create(table);

            tableParty.id = c1TpId;
            tableParty.tableId = c1tId;
            tableParty.tableName = table.name;
            tableParty.tableGroupId = "";
            tableParty.openedTime = new Date().getTime();
            tableParty.cleaningTime = "";
            tableParty.closedTime = "";
            tableParty.status = "cleaning";
            await ctx.Create(tableParty);


        }

        before(async () => {
            await clearData();
            await initData();
        })

        it("不存在的台次", async () => {
            try {
                let rst = tableService.FinishCleanTable({
                    tableId: tableId
                });
            }
            catch (e) {
                assert.equal(e.Message, "台次与台桌不符合", "不存在的台次错误");
            }
        });

        it("不存在的台桌", async () => {
            try {
                let rst = tableService.FinishCleanTable({
                    tableId: "tableId"
                });
            }
            catch (e) {
                assert.equal(e.Message, "台次与台桌不符合", "不存在的台桌错误");
            }
        });

        it("台次与台桌不符合", async () => {
            try {
                let rst = tableService.FinishCleanTable({
                    tableId: tId
                });
            }
            catch (e) {
                assert.equal(e.Message, "台次与台桌不符合", "台次与台桌不符合错误");
            }
        });

        it("台桌状态非cleaning状态", async () => {
            try {
                let rst = tableService.FinishCleanTable({
                    tableId: tId
                });
            }
            catch (e) {
                assert.equal(e.Message, "非待清台状态，清台失败", "台桌状态非cleaning状态错误");
            }
        });

        it("台次状态非cleaning状态", async () => {
            try {
                let rst = tableService.FinishCleanTable({
                    tableId: ftId
                });
            }
            catch (e) {
                assert.equal(e.Message, "清台失败！", "台次状态非cleaning状态错误");
            }
        });

        it("无清台员清理台桌", async () => {
            let rst = await tableService.FinishCleanTable({
                tableId: c1tId
            })
            assert.equal(rst.tableParty.id, c1TpId, "无清台员清理错误");
        });

        it("有清台员清理台桌", async () => {
            let rst = await tableService.FinishCleanTable({
                tableId: ctId,
                bussers: [{ id: "ddd", name: "sddd" }]
            })
            assert.equal(rst.tableParty.busser[0].id, "ddd", "有清台员清理错误");
        });
    })


    describe("CleanData", () => {
        async function clearTpData() {
            let tableList = await ctx.Table.ToList();
            for (let t of tableList) {
                await ctx.Delete(t);
            }

            let tablePartyList = await ctx.TableParty.ToList();
            for (let tp of tablePartyList) {
                await ctx.Delete(tp);
            }
        }


        async function initTPData() {
            await clearTpData();
            let tpStatus = ["closed", "opening", "cleaning"];

            for (let i = 0; i < 50; i++) {
                let tp = new TableParty();
                tp.id = Guid.GetGuid();
                tp.status = tpStatus[i % 3];
                tp.openedTime = new Date().getTime() - 345600000;  //构造两天前的数据
                tp.storeId = "2a8mmqsc5kw0k4g00co4gko0c";

                await ctx.Create(tp);

                tp.id = Guid.GetGuid();
                tp.openedTime = new Date().getTime();  //构造当天的数据
                await ctx.Create(tp);
            }
        }

        async function initExTPData() {
            await clearTpData();

            let orderList = await ctx.Order.ToList();
            for(let o of orderList){
                await ctx.Delete(o);
            }

            let tpStatus = ["closed", "opening", "cleaning"];
            let tableStatus = ["opening", "closed", null];
            let orderStatus = ["ordered", "merged", "closed", "init"];

            for (let i = 0; i < 50; i++) {
                let table = new Table();
                table.id = Guid.GetGuid();
                table.name = "台桌" + i;
                table.capacity = 1;
                table.zone = null;
                table.storeId = "2a8mmqsc5kw0k4g00co4gko0c";
                table.showOrder = 1;
                table.status = tableStatus[i % 3];
                table.lock = null;
                table.feeRuleId = null;
                await ctx.Create(table);

                let order = new Order();
                order.id = Guid.GetGuid();
                order.status = orderStatus[i % 3];
                await ctx.Create(order);

                let tp = new TableParty();
                tp.id = Guid.GetGuid();
                tp.tableId = table.id;
                tp.storeId = table.storeId;
                tp.tableName = table.name;
                tp.openedTime = new Date().getTime();
                tp.status = tpStatus[i % 4];
                tp.orderId = order.id;

                await ctx.Create(tp);
            }
        }

        it("清理两天前的台次-【有】数据清理", async () => {
            await initTPData();
            await tableService.CleanData();
            let rst = await ctx.TableParty.ToList();
            assert.equal(rst.length, 67, "【有】数据清理错误");
        });
        it("清理两天前的台次-【无】数据清理", async () => {
            await tableService.CleanData();
            let rst = await ctx.TableParty.ToList();
            assert.equal(rst.length, 67, "【无】数据清理错误");
        });

        it("【有】清理异常台次", async () => {
            await initExTPData();
            await tableService.CleanData();
            let rst = await ctx.TableParty.Where(x => x.status == "closed").ToList();
            assert.equal(rst.length, 25, "【有】台桌清理异常");
        });
        it("【无】清理异常台次", async () => {
            let rst = await ctx.TableParty.Where(x => x.status == "closed").ToList();
            assert.equal(rst.length, 25, "【无】台桌清理异常");
        });
    });
})